import {
  Button,
  Divider,
  Form,
  FormItem,
  Input,
  message,
  notification,
  Space,
  Spin,
  Upload
} from 'ant-design-vue'
import { computed, defineComponent, nextTick, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'

import { commonApi, marketingApi } from '@/apis'
import {
  type ProEditorProps,
  type ProEditorRef,
  ProEditor,
  SvgIcon
} from '@/components'
import { useBack } from '@/hooks'

import styles from './index.module.css'

const { useForm } = Form

export default defineComponent({
  name: 'CommodityDetail',
  setup() {
    const loading = ref(false)
    const formModel = ref({
      goodsCode: '',
      goodsName: '',
      goodsImage: '',
      headImage: '',
      description: ''
    })
    const formRules = ref({
      goodsCode: [{ required: true, message: '请输入', trigger: 'blur' }],
      goodsName: [{ required: true, message: '请输入', trigger: 'blur' }],
      goodsImage: [
        {
          required: true,
          validator: () => {
            if (fileList.value.goodsImage.length === 0) {
              return Promise.reject('请上传')
            }

            return Promise.resolve()
          }
        }
      ],
      headImage: [
        {
          required: true,
          validator: () => {
            if (fileList.value.headImage.length === 0) {
              return Promise.reject('请上传')
            }

            return Promise.resolve()
          }
        }
      ],
      description: [{ required: true, message: '请输入', trigger: 'blur' }]
    } as FormRules)
    const editorRef = ref({} as ProEditorRef)
    const editorConfig = ref({
      editorStyle: {
        height: '300px'
      },
      editorHtml: '',
      editorVisible: false,
      editorConfig: {
        MENU_CONF: {
          uploadImage: {
            server: commonApi.uploadFileUrl,
            fieldName: 'file',
            customInsert(res: any, insertFn: any) {
              // res 即服务端的返回结果
              const url = res.data

              // 从 res 中找到 url alt href ，然后插图图片
              insertFn(url, '', '')
            },
            maxFileSize: 10 * 1024 * 1024,
            onError(file: File, err: any, res: any) {
              if (file && file.size > 10 * 1024 * 1024) {
                message.error('图片超过10M，请压缩图片或分段上传')
              }
            }
          }
        } as any
      },
      toolbarConfig: {
        excludeKeys: ['group-video']
      }
    } as ProEditorProps)
    const isEdit = ref(false)
    const fileList = ref({
      goodsImage: [] as any[],
      headImage: [] as any[]
    })

    const formRef = useForm(formModel, formRules)

    const route = useRoute()

    const id = computed(() => Number(route.query.id))

    const { handleCancel } = useBack('refreshExchangeCommodity')

    function handleUploadChange(
      key: 'goodsImage' | 'headImage',
      params: FileInfo
    ) {
      fileList.value[key] = params.fileList

      if (params.file.status === 'done') {
        fileList.value[key].find(v => v.uid === params.file.uid).url =
          params.file.response.data
      }
    }

    function handleSubmit() {
      const editorData = editorRef.value.editor.getHtml()
      formModel.value.description = editorData

      nextTick(() => {
        formRef
          .validate()
          .then(async () => {
            try {
              loading.value = true
              const data = {
                ...formModel.value,
                pointGoodsId: id.value,
                headImage: fileList.value.headImage.map(v => v.url).join(','),
                goodsImage: fileList.value.goodsImage[0].url
              }

              isEdit.value
                ? await marketingApi.updateCommodityDetail(data)
                : await marketingApi.createCommodityDetail(data)
              notification.success({
                message: (isEdit.value ? '编辑' : '新建') + '商品详情成功',
                duration: 1.5
              })
              handleCancel()
            } finally {
              loading.value = false
            }
          })
          .catch(errors => {
            console.log(errors)
          })
      })
    }

    async function init() {
      try {
        loading.value = true

        const res = await marketingApi.getCommodityDetail(id.value)

        if (res) {
          isEdit.value = true
          Object.assign(formModel.value, res)

          fileList.value.goodsImage = [
            {
              uid: Math.random().toString().slice(-5),
              url: formModel.value.goodsImage
            }
          ]
          fileList.value.headImage = formModel.value.headImage
            .split(',')
            .map(v => ({
              uid: Math.random().toString().slice(-5),
              url: v
            }))
        }

        editorConfig.value.editorHtml = formModel.value.description
        editorConfig.value.editorVisible = true
      } finally {
        loading.value = false
      }
    }

    onMounted(() => {
      init()
    })

    return {
      loading,
      formModel,
      formRef,
      editorRef,
      editorConfig,
      fileList,
      handleUploadChange,
      handleCancel,
      handleSubmit
    }
  },
  render() {
    return (
      <div class={styles.view}>
        <Spin spinning={this.loading}>
          <Form labelCol={{ span: 4 }} wrapperCol={{ span: 14 }}>
            <FormItem
              label="商品编码"
              {...this.formRef.validateInfos['goodsCode']}
            >
              <Input v-model:value={this.formModel.goodsCode} />
            </FormItem>
            <FormItem
              label="商品名称"
              {...this.formRef.validateInfos['goodsName']}
            >
              <Input
                v-model:value={this.formModel.goodsName}
                v-slots={{
                  suffix: () => (
                    <span>{this.formModel.goodsName.length}/50</span>
                  )
                }}
                maxlength={50}
              />
            </FormItem>
            <FormItem
              label="商品图片"
              {...this.formRef.validateInfos['goodsImage']}
            >
              <Upload
                action={commonApi.uploadFileUrl}
                accept="image/*"
                listType="picture-card"
                fileList={this.fileList.goodsImage}
                showUploadList={{
                  showPreviewIcon: false,
                  showRemoveIcon: true
                }}
                onChange={args => this.handleUploadChange('goodsImage', args)}
              >
                {this.fileList.goodsImage.length < 1 ? (
                  <div>
                    <SvgIcon name="upload" />
                    <div class="ant-upload-text"></div>
                  </div>
                ) : null}
              </Upload>
              <span class={styles.desc}>建议200*200像素</span>
            </FormItem>
            <FormItem
              label="头部图片"
              {...this.formRef.validateInfos['headImage']}
            >
              <Upload
                action={commonApi.uploadFileUrl}
                accept="image/*"
                listType="picture-card"
                fileList={this.fileList.headImage}
                showUploadList={{
                  showPreviewIcon: false,
                  showRemoveIcon: true
                }}
                onChange={args => this.handleUploadChange('headImage', args)}
              >
                {this.fileList.headImage.length < 5 ? (
                  <div>
                    <SvgIcon name="upload" />
                    <div class="ant-upload-text"></div>
                  </div>
                ) : null}
              </Upload>
              <span class={styles.desc}>建议800*800像素</span>
            </FormItem>
            <FormItem
              label="商品描述"
              {...this.formRef.validateInfos['description']}
            >
              <ProEditor ref="editorRef" {...this.editorConfig} />
            </FormItem>
            <Divider />
            <FormItem class={styles.formBtns} wrapperCol={{ span: 10 }}>
              <Space>
                <Button onClick={this.handleCancel}>取消</Button>
                <Button type="primary" onClick={this.handleSubmit}>
                  确定
                </Button>
              </Space>
            </FormItem>
          </Form>
        </Spin>
      </div>
    )
  }
})
